package top.kangyaocoding.ecommerce.impl;

import com.upyun.RestManager;
import com.upyun.UpException;
import com.upyun.UpYunUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import top.kangyaocoding.ecommerce.IFileService;
import top.kangyaocoding.ecommerce.constants.Constants;
import top.kangyaocoding.ecommerce.response.Response;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Random;

/**
 * 描述: 文件服务实现类
 *
 * @author K·Herbert
 * @since 2025-03-16 15:56
 */
@Slf4j
@Service
public class FileService implements IFileService {

    @Value("${upyun.bucket.name}")
    private String bucketName;

    @Value("${upyun.operator.name}")
    private String operatorName;

    @Value("${upyun.operator.password}")
    private String operatorPassword;

    @Value("${upyun.dir}")
    private String uploadPath;

    @Value("${upyun.url}")
    private String uploadUrl;

    public Response<String> uploadFile(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            log.error("文件为空！");
            return Response.<String>builder()
                    .code(Constants.ErrorCode.UN_ERROR.getCode())
                    .info(Constants.ErrorCode.UN_ERROR.getInfo())
                    .data("文件为空！")
                    .build();
        }
        // 生成文件名
        String fileName = generateFileName() + getFileExtension(Objects.requireNonNull(file.getOriginalFilename()));
        // 初始化
        RestManager manager = new RestManager(bucketName, operatorName, operatorPassword);
        Map<String, String> params = new HashMap<>();
        try {
            // GMT格式时间
            params.put(RestManager.PARAMS.CONTENT_MD5.getValue(), UpYunUtils.md5(file.getBytes()));
            params.put("Date", UpYunUtils.getGMTDate());
            params.put("Content-Length", String.valueOf(file.getSize()));

            okhttp3.Response response = manager.writeFile(uploadPath + fileName, file.getBytes(), params);
            if (response.code() != 200) {
                log.error("上传失败，错误码：{}，错误信息：{}", response.code(), response.message());
                return Response.<String>builder()
                        .code(Constants.ErrorCode.UN_ERROR.getCode())
                        .info(Constants.ErrorCode.UN_ERROR.getInfo())
                        .data("未知错误，上传失败！")
                        .build();
            }
        } catch (UpException | IOException e) {
            throw new RuntimeException(e);
        }
        String url = uploadUrl + uploadPath + fileName;
        log.info("上传成功，访问URL：{}", url);
        // 返回访问URL
        return Response.<String>builder()
                .code(Constants.ErrorCode.SUCCESS.getCode())
                .info(Constants.ErrorCode.SUCCESS.getInfo())
                .data(url)
                .build();
    }

    private String generateFileName() {
        // 使用时间戳格式
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"));
        // 生成随机的八个英文小写字母
        String randomChars = generateRandomChars();
        // 拼接时间戳和随机字符
        return timestamp + "-" + randomChars;
    }

    private String generateRandomChars() {
        Random random = new Random();
        StringBuilder sb = new StringBuilder(8);
        for (int i = 0; i < 8; i++) {
            // 生成随机的英文小写字母（范围是 'a' 到 'z'）
            char randomChar = (char) ('a' + random.nextInt(26));
            sb.append(randomChar);
        }
        return sb.toString();
    }

    private String getFileExtension(String filename) {
        return filename.substring(filename.lastIndexOf("."));
    }
}
